package com.jtny.nytb.dataparam.service.serviceImpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jtny.component.core.domain.BaseDO;
import com.jtny.component.core.util.PageUtils;
import com.jtny.component.entity.PageData;
import com.jtny.component.enums.GenericStatusEnum;
import com.jtny.component.exception.ServiceException;
import com.jtny.component.util.Assert;
import com.jtny.component.util.BeanUtils;
import com.jtny.nytb.config.dataalarm.dao.DataAlarmDAO;
import com.jtny.nytb.config.dataalarm.domain.DataAlarmDO;
//import com.jtny.nytb.config.datafactor.enums.DataParamSourceEnum;
import com.jtny.nytb.dataparam.bo.ItemBO;
import com.jtny.nytb.dataparam.dao.*;
import com.jtny.nytb.dataparam.domain.*;
import com.jtny.nytb.dataparam.property.CodeRuleProperty;
import com.jtny.nytb.dataparam.service.DataParamService;
import com.jtny.nytb.dataparam.vo.*;
import com.jtny.nytb.equipment.dao.dataalgorithm.DataAlgorithmDAO;
import com.jtny.nytb.equipment.dao.dataalgorithm.DataAlgorithmFormulaConfigDAO;
import com.jtny.nytb.equipment.dao.dataalgorithm.DataAlgorithmParamConfigDAO;
import com.jtny.nytb.equipment.dao.dataalgorithm.DataAlgorithmScriptConfigDAO;
import com.jtny.nytb.equipment.domain.dataalgorithm.DataAlgorithmDO;
import com.jtny.nytb.equipment.domain.dataalgorithm.DataAlgorithmFormulaConfigDO;
import com.jtny.nytb.equipment.domain.dataalgorithm.DataAlgorithmParamConfigDO;
import com.jtny.nytb.equipment.domain.dataalgorithm.DataAlgorithmScriptConfigDO;
import com.jtny.nytb.equipment.domain.datalabel.DataLabelDO;
import com.jtny.nytb.equipment.domain.datalabel.DataLabelItemDO;
import com.jtny.nytb.equipment.enums.DataParamSourceEnum;
import com.jtny.nytb.equipment.service.impl.DataAlgorithmBizImpl;
import com.jtny.nytb.equipment.utils.EasyExcelUtils;
import com.jtny.nytb.equipment.vo.dataparam.AlgorithmExcelVO;
import com.jtny.nytb.equipment.vo.excel.ExcelAlarmVO;
import com.jtny.nytb.equipment.vo.excel.ExcelAlgorithmParamVO;
import com.jtny.nytb.equipment.vo.excel.ExcelFrequencyVO;
import com.jtny.nytb.excel.utils.DataExportBaseExcel;
import com.jtny.nytb.excel.utils.DataParamExportExcel;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class ConfigDataParamServiceImpl extends ServiceImpl<ConfigDataParamManagementDAO,ConfigDataParamManagementDO> implements DataParamService {
    private ConfigDataParamManagementDAO dataParamManagementDAO;
    private ConfigDataParamAlgorithmRelationDAO algorithmRelationDAO;
    private DataAlarmDAO dataAlarmDAO;
    private ConfigDataParamAlarmRelationDAO configDataParamAlarmRelationDAO;
    private ConfigDataParamAlgorithmParamRelationDAO paramRelationDAO;
    private DataAlgorithmDAO dataAlgorithmDAO;
    private DataAlgorithmFormulaConfigDAO dataAlgorithmFormulaConfigDAO;
    private DataAlgorithmParamConfigDAO dataAlgorithmParamConfigDAO;
    private DataAlgorithmScriptConfigDAO scriptConfigDAO;
    private DataAlgorithmBizImpl dataAlgorithmServiceImpl;
    private ConfigRuleManagementServiceImpl configRuleManagementServiceImpl;
    private CodeRuleProperty codeRuleProperty;
    private DataParamAsyncServiceImpl dataParamAsyncService;

    /**
     * 通过名称进行查询是否存在
     */
    @Override
    public List<ConfigDataParamManagementVO> queryByName(String name) {
        List<ConfigDataParamManagementDO> configDataParamManagementDOList = dataParamManagementDAO
                .selectList(Wrappers.<ConfigDataParamManagementDO>lambdaQuery().eq(ConfigDataParamManagementDO::getStatus, 0)
                        .eq(ConfigDataParamManagementDO::getName, name));
        if (CollUtil.isEmpty(configDataParamManagementDOList)) {
            return CollUtil.newArrayList();
        }
        return BeanUtils.copyToList(configDataParamManagementDOList, ConfigDataParamManagementVO.class);
    }

    /**
     * 保存数据变量管理
     */
//    @Transactional(rollbackFor = ServiceException.class)
    @Override
    public ConfigDataParamManagementVO save(ConfigDataParamManagementVO configDataParamManagementVO) throws ServiceException {
        Assert.notNull(configDataParamManagementVO, "数据参量数据异常");
        Assert.notNull(configDataParamManagementVO.getCode(), "数据参量数据异常");
        // 插入数据变量管理的基础信息
        ConfigDataParamManagementDO configDataParamManagementDO = BeanUtils.copyToObject(configDataParamManagementVO, ConfigDataParamManagementDO.class);
        dataParamManagementDAO.insert(configDataParamManagementDO);
        // 设置id
        configDataParamManagementVO.setId(configDataParamManagementDO.getId());

        // 插入数据变量算法依赖和参数依赖
        dataParamAsyncService.saveOrUpdateAlgorithm(configDataParamManagementVO, configDataParamManagementDO.getId());

        // 插入报警点数据
        dataParamAsyncService.saveOrUpdateAlarmList(configDataParamManagementVO, configDataParamManagementDO);
        // 返回值摄入id
        configDataParamManagementVO.setId(configDataParamManagementDO.getId());
        return configDataParamManagementVO;
    }

    /**
     * 通过id查询变量管理数据
     */
    @Override
    public ConfigDataParamManagementVO queryById(Long id) {
        // 查询变量管理的基础表信息
        ConfigDataParamManagementDO configDataParamManagementDO = dataParamManagementDAO
                .selectOne(Wrappers.<ConfigDataParamManagementDO>lambdaQuery()
                        .ne(ConfigDataParamManagementDO::getStatus, 9)
                        .eq(ConfigDataParamManagementDO::getId, id));

        if (configDataParamManagementDO == null) {
            log.warn("ConfigDataParamManagementDO with id " + id +" not found");
            return null;
        }

        ConfigDataParamManagementVO configDataParamManagementVO = BeanUtils.copyToObject(configDataParamManagementDO, ConfigDataParamManagementVO.class);

        // 设置相关的 VO 对象
        Map<Long, ConfigAlgorithVO> algorithmMap = mapAlgorithm(Collections.singletonList(id));
        if (algorithmMap != null) {
            configDataParamManagementVO.setConfigAlgorithVO(algorithmMap.get(id));
        }

        Map<Long, List<ConfigParamVO>> configParamMap = mapConfigParamList(Collections.singletonList(configDataParamManagementVO));
        if (configParamMap != null) {
            configDataParamManagementVO.setConfigParamVOList(configParamMap.get(id));
        }

        Map<Long, List<ConfigAlarmVO>> configAlarmMap = mapDataLabelList(Collections.singletonList(id));
        if (configAlarmMap != null) {
            configDataParamManagementVO.setConfigAlarmVOList(configAlarmMap.get(id));
        }

        return configDataParamManagementVO;
    }

    /**
     * 按名称获取
     */
    @Override
    public ConfigDataParamManagementVO getByName(String name) {
        // 查询变量管理的基础表信息
        ConfigDataParamManagementDO configDataParamManagementDO = dataParamManagementDAO
                .selectOne(Wrappers.<ConfigDataParamManagementDO>lambdaQuery()
                        .ne(ConfigDataParamManagementDO::getStatus, 9)
                        .eq(ConfigDataParamManagementDO::getName, name).last("limit 1"));
        if (Objects.isNull(configDataParamManagementDO)) {
            return null;
        }
        return BeanUtils.copyToObject(configDataParamManagementDO, ConfigDataParamManagementVO.class);
    }

    /**
     * map 获取算法数据
     */
    private Map<Long, ConfigAlgorithVO> mapAlgorithm(List<Long> dataParamIds) {
        List<ConfigDataParamAlgorithmRelationDO> relationList = algorithmRelationDAO
                .selectList(Wrappers.<ConfigDataParamAlgorithmRelationDO>lambdaQuery()
                        .in(ConfigDataParamAlgorithmRelationDO::getDataParamId, dataParamIds));
        // 没有数据
        if (CollUtil.isEmpty(relationList)) {
            return Collections.emptyMap();
        }
        // 1 : 1 key : dataParamId value : algorithmId
        Map<Long, Long> mapRelation = relationList.stream()
                .collect(Collectors
                        .toMap(ConfigDataParamAlgorithmRelationDO::getDataParamId,
                                ConfigDataParamAlgorithmRelationDO::getAlgorithmId));
        List<DataAlgorithmDO> algorithmList = dataAlgorithmDAO.selectBatchIds(mapRelation.values());
        if (CollUtil.isEmpty(algorithmList)) {
            return Collections.emptyMap();
        }
        Map<Long, DataAlgorithmDO> mapAlgorithm = algorithmList.stream().collect(Collectors.toMap(DataAlgorithmDO::getId, item -> item));


        List<Long> algorithmIds4Formula = new ArrayList<>();
        List<Long> algorithmIds4Script = new ArrayList<>();
        algorithmList.forEach(item -> {
            if ("计算公式配置".equals(item.getConfigurationScheme())) {
                algorithmIds4Formula.add(item.getId());
            } else {
                algorithmIds4Script.add(item.getId());
            }
        });

        Map<Long, List<String>> formulaMap = new HashMap<>();
        if (CollUtil.isNotEmpty(algorithmIds4Formula)) {
            List<DataAlgorithmFormulaConfigDO> dataAlgorithmFormulaConfigDOS = dataAlgorithmFormulaConfigDAO.selectList(Wrappers.<DataAlgorithmFormulaConfigDO>lambdaQuery()
                    .in(DataAlgorithmFormulaConfigDO::getAlgorithmId, algorithmIds4Formula));
            formulaMap = dataAlgorithmFormulaConfigDOS.stream().collect(Collectors.groupingBy(DataAlgorithmFormulaConfigDO::getAlgorithmId,
                    Collectors.mapping(DataAlgorithmFormulaConfigDO::getFormula, Collectors.toList())));
        }

        Map<Long, List<DataAlgorithmScriptConfigDO>> scriptMap = new HashMap<>();
        if (CollUtil.isNotEmpty(algorithmIds4Script)) {
            List<DataAlgorithmScriptConfigDO> dataAlgorithmScriptConfigDOS = scriptConfigDAO.selectList(Wrappers.<DataAlgorithmScriptConfigDO>lambdaQuery()
                    .in(DataAlgorithmScriptConfigDO::getAlgorithmId, algorithmIds4Script));
            scriptMap = dataAlgorithmScriptConfigDOS.stream().collect(Collectors.groupingBy(DataAlgorithmScriptConfigDO::getAlgorithmId,
                    Collectors.mapping(item -> item, Collectors.toList())));
        }

        Map<Long, ConfigAlgorithVO> result = new HashMap<>(mapRelation.size());
        Map<Long, List<DataAlgorithmScriptConfigDO>> finalScriptMap = scriptMap;
        Map<Long, List<String>> finalFormulaMap = formulaMap;
        dataParamIds.forEach(id -> {
            Long algorithmId = mapRelation.get(id);
            result.put(id, configAlgorithVO(mapAlgorithm.getOrDefault(algorithmId, new DataAlgorithmDO()),
                    finalFormulaMap.getOrDefault(algorithmId, new ArrayList<>()),
                    finalScriptMap.getOrDefault(algorithmId, new ArrayList<>())));
        });
        return result;
    }

    private ConfigAlgorithVO configAlgorithVO(DataAlgorithmDO dataAlgorithmDO,
                                                List<String> formulaList,
                                                List<DataAlgorithmScriptConfigDO> scriptList) {
        ConfigAlgorithVO configAlgorithVO = new ConfigAlgorithVO();
        configAlgorithVO.setAlgorithId(dataAlgorithmDO.getId());
        configAlgorithVO.setAlgorithName(dataAlgorithmDO.getName());
        configAlgorithVO.setAlgorithmType(dataAlgorithmDO.getType());

        configAlgorithVO.setAlgorithDescription(dataAlgorithmDO.getDescription());
        configAlgorithVO.setAlgorithAccuracyDigit(dataAlgorithmDO.getAccuracyDigit());

        configAlgorithVO.setAlgorithConfigurationScheme(dataAlgorithmDO.getConfigurationScheme());
        if ("计算公式配置".equals(dataAlgorithmDO.getConfigurationScheme())) {
            if (!formulaList.isEmpty()) {
                configAlgorithVO.setAlgorithFormula(formulaList.get(0));
            }
        } else {
            if (!scriptList.isEmpty()) {
                DataAlgorithmScriptConfigDO dataAlgorithmScriptConfigDO = scriptList.get(0);
                Optional.ofNullable(dataAlgorithmScriptConfigDO).ifPresent(item -> {
                    configAlgorithVO.setScriptPath(item.getScriptPath());
                    configAlgorithVO.setRequestType(item.getRequestType());
                });
            }
        }
        return configAlgorithVO;
    }

    /**
     * map 获取算法参数数据
     */
    private Map<Long, List<ConfigParamVO>> mapConfigParamList(List<ConfigDataParamManagementVO> dataParamManagementVOList) {
        List<Long> dataParamIds = dataParamManagementVOList.stream().map(ConfigDataParamManagementVO::getId).collect(Collectors.toList());

        List<ConfigDataParamAlgorithmRelationDO> relationList = algorithmRelationDAO
                .selectList(Wrappers.<ConfigDataParamAlgorithmRelationDO>lambdaQuery()
                        .in(ConfigDataParamAlgorithmRelationDO::getDataParamId, dataParamIds));
        // 没有数据
        if (CollUtil.isEmpty(relationList)) {
            return Collections.emptyMap();
        }
        // 1 : 1 map key : dataParamId value : algorithmId
        Map<Long, Long> mapRelation = relationList.stream().collect(Collectors.toMap(ConfigDataParamAlgorithmRelationDO::getDataParamId, ConfigDataParamAlgorithmRelationDO::getAlgorithmId));

        // 所有算法参数关联
        List<DataAlgorithmFormulaConfigDO> dataAlgorithmFormulaConfigDOS = dataAlgorithmFormulaConfigDAO.selectList(Wrappers.<DataAlgorithmFormulaConfigDO>lambdaQuery()
                .in(DataAlgorithmFormulaConfigDO::getAlgorithmId, mapRelation.values()));

        if (CollUtil.isEmpty(dataAlgorithmFormulaConfigDOS)) {
            return Collections.emptyMap();
        }
        // map key : 算法id value : 参数ids
        Map<Long, List<Long>> mapParamList = dataAlgorithmFormulaConfigDOS.stream()
                .collect(Collectors.groupingBy(DataAlgorithmFormulaConfigDO::getAlgorithmId,
                        Collectors.mapping(DataAlgorithmFormulaConfigDO::getAlgorithmParamId, Collectors.toList())));
        // list 参数ids
        List<Long> algorithmParamIdList = dataAlgorithmFormulaConfigDOS.stream().map(DataAlgorithmFormulaConfigDO::getAlgorithmParamId).collect(Collectors.toList());
        List<DataAlgorithmParamConfigDO> dataAlgorithmParamConfigList = dataAlgorithmParamConfigDAO.selectBatchIds(algorithmParamIdList);

        List<ConfigDataParamAlgorithmParamRelationDO> paramDataParamRelationList = paramRelationDAO.selectList(Wrappers.<ConfigDataParamAlgorithmParamRelationDO>lambdaQuery()
                .in(ConfigDataParamAlgorithmParamRelationDO::getAlgorithParamId, algorithmParamIdList)
                .isNotNull(ConfigDataParamAlgorithmParamRelationDO::getDataParamId)
                .isNotNull(ConfigDataParamAlgorithmParamRelationDO::getParentParamId));
        Map<String, ConfigDataParamManagementDO> dataParamManagementMap = new HashMap<>();
        if (CollUtil.isNotEmpty(paramDataParamRelationList)) {
            // map key : 算法参数id_dataParamParentId  value : dataParamId
            Map<String, Long> tempMap = paramDataParamRelationList.stream().collect(Collectors.toMap(item -> item.getAlgorithParamId() + "_" + item.getParentParamId(), ConfigDataParamAlgorithmParamRelationDO::getDataParamId));
            // 被关联的dataParamIds
            Collection<Long> bindDataParamIds = tempMap.values();
            List<ConfigDataParamManagementDO> dataParamManagementDOS = dataParamManagementDAO.selectBatchIds(bindDataParamIds);
            Map<Long, ConfigDataParamManagementDO> collect = dataParamManagementDOS.stream().collect(Collectors.toMap(ConfigDataParamManagementDO::getId, item -> item));
            for (String key : tempMap.keySet()) {
                Long dataParamId = tempMap.get(key);
                ConfigDataParamManagementDO configDataParamManagementDO = collect.get(dataParamId);
                dataParamManagementMap.put(key, configDataParamManagementDO);
            }
        }


        if (CollUtil.isEmpty(dataAlgorithmParamConfigList)) {
            return Collections.emptyMap();
        }
        // map key : 参数id value : 参数
        Map<Long, DataAlgorithmParamConfigDO> mapParam = dataAlgorithmParamConfigList.stream()
                .collect(Collectors.toMap(DataAlgorithmParamConfigDO::getId, item -> item));

        Map<Long, List<ConfigParamVO>> result = new HashMap<>(mapRelation.size());
        dataParamManagementVOList.forEach(dataParam -> {
            Long id = dataParam.getId();
            Long algorithmId = mapRelation.get(id);
            List<Long> paramIds = mapParamList.get(algorithmId);
            if (CollUtil.isNotEmpty(paramIds)) {
                List<ConfigParamVO> configParamVOList = paramIds.stream()
                        .map(mapParam::get)
                        .map(item -> configParamVO(item, dataParamManagementMap, id))
                        .collect(Collectors.toList());
                result.put(id, configParamVOList);
            }
        });

        return result;
    }

    private ConfigParamVO configParamVO(DataAlgorithmParamConfigDO dataAlgorithmParamConfigDO,
                                          Map<String, ConfigDataParamManagementDO> dataParamManagementMap,
                                          Long paramId) {
        ConfigParamVO configParamVO = new ConfigParamVO();
        if(Objects.isNull(dataAlgorithmParamConfigDO)){
            return configParamVO;
        }
        configParamVO.setParamId(dataAlgorithmParamConfigDO.getId());
        configParamVO.setParamSign(dataAlgorithmParamConfigDO.getMark());
        configParamVO.setParamdesc(dataAlgorithmParamConfigDO.getDescription());
        configParamVO.setParamType(dataAlgorithmParamConfigDO.getMappedType());
        String ALGORITHM_TYPE_FORMULA = "参量";
        if (ALGORITHM_TYPE_FORMULA.equals(configParamVO.getParamType())) {
            ConfigDataParamManagementDO bindInfo = dataParamManagementMap
                    .getOrDefault(dataAlgorithmParamConfigDO.getId() + StrPool.UNDERLINE + paramId, new ConfigDataParamManagementDO());
            if (ObjectUtil.isNotEmpty(bindInfo)) {
                configParamVO.setVariableId(bindInfo.getId());
                configParamVO.setVariableValue(bindInfo.getCode());
                configParamVO.setVariableDeclaration(bindInfo.getName());
            }
        } else {
            configParamVO.setVariableValue(dataAlgorithmParamConfigDO.getGlobalVariableValue());
            configParamVO.setVariableDeclaration(dataAlgorithmParamConfigDO.getGlobalVariableDescription());
        }
        return configParamVO;
    }

    /**
     * map 获取警告数据
     */
    private Map<Long, List<ConfigAlarmVO>> mapDataLabelList(List<Long> dataParamIds) {
        List<DataAlarmDO> dataAlarmDOS = dataAlarmDAO.selectList(Wrappers.<DataAlarmDO>lambdaQuery()
                .in(DataAlarmDO::getDataParamId, dataParamIds));
        if (CollUtil.isEmpty(dataAlarmDOS)) {
            return Collections.emptyMap();
        }

        Map<Long, List<DataAlarmDO>> collect = dataAlarmDOS.stream().collect(Collectors.groupingBy(DataAlarmDO::getDataParamId));
        return collect.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            List<DataAlarmDO> value = entry.getValue();
            return BeanUtils.copyToList(value, ConfigAlarmVO.class);
        }));
    }


    /**
     * 更新数据
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ConfigDataParamManagementVO update(ConfigDataParamManagementVO configDataParamManagementVO) throws ServiceException {
        // 查询原本信息
        ConfigDataParamManagementDO existDataParamManagementDO = dataParamManagementDAO.selectById(configDataParamManagementVO.getId());
        // 第一步：更新基本信息
        ConfigDataParamManagementDO configDataParamManagementDO = BeanUtils.copyToObject(configDataParamManagementVO, ConfigDataParamManagementDO.class);
        dataParamManagementDAO.updateById(configDataParamManagementDO);
        // 更新算法和参数依赖
        dataParamAsyncService.saveOrUpdateAlgorithm(configDataParamManagementVO, existDataParamManagementDO.getId());
        // 更新报警信息
        dataParamAsyncService.saveOrUpdateAlarmList(configDataParamManagementVO, configDataParamManagementDO);
        return configDataParamManagementVO;
    }

    private static void setTypeName(ConfigDataParamManagementVO managementDTO, ConfigDataParamManagementVO managementVO) {
        switch (managementDTO.getSource()){
            case 1:
                managementVO.setSourceName("设备自动采集");
                break;
            case 2:
                managementVO.setSourceName("系统计算");
                break;
            case 3:
                managementVO.setSourceName("常量");
                break;
            case 4:
                managementVO.setSourceName("手动填报");
                break;
            default:
                managementVO.setSourceName("");
        }
        if (ObjectUtil.isNull(managementDTO.getDataType())) {
            return;
        }

        switch (managementDTO.getDataType()){
            case 1:
                managementVO.setDataTypeName("实时量");
                break;
            case 2:
                managementVO.setDataTypeName("累计量");
                break;
            default:
                managementVO.setDataTypeName("");
        }
    }
    @Override
    public PageData<ConfigDataParamManagementVO> queryByPage(ConfigDataParamManagementPageVO configDataParamManagementPageVO) {
        PageData<ConfigDataParamManagementVO> managementDTOPageData = this.queryPage(configDataParamManagementPageVO);
        Collection<ConfigDataParamManagementVO> dataList = managementDTOPageData.getData();
        PageData<ConfigDataParamManagementVO> managementVOPage = managementDTOPageData.transformData(ConfigDataParamManagementVO.class);
        // 数据为空，直接返回
        if (CollUtil.isEmpty(dataList)){
            return managementVOPage;
        }
        List<ConfigDataParamManagementVO> managementVOList = new ArrayList<>();
        dataList.forEach(managementDTO -> {
            ConfigDataParamManagementVO managementVO = BeanUtils.copyToObject(managementDTO, ConfigDataParamManagementVO.class);
            setTypeName(managementDTO, managementVO);
            managementVOList.add(managementVO);
        });
        managementVOPage.setData(managementVOList);
        return managementVOPage;
    }

    /**
     * 分页查询
     */
    @Override
    public PageData<ConfigDataParamManagementVO> queryPage(ConfigDataParamManagementPageVO paramManagementPageVO) {
        // 刷选如果含有算法的id，
        List<Long> findManageIdList = new ArrayList<>();
        if (paramManagementPageVO.getAlgorithmId() != null && paramManagementPageVO.getAlgorithmId() != 0) {
            QueryWrapper<ConfigDataParamAlgorithmRelationDO> wrapper = new QueryWrapper<>();
            wrapper.eq("algorithm_id", paramManagementPageVO.getAlgorithmId());
            List<ConfigDataParamAlgorithmRelationDO> configDataParamAlgorithmRelationDOList = algorithmRelationDAO.selectList(wrapper);
            if (CollUtil.isEmpty(configDataParamAlgorithmRelationDOList)) {
                return new PageData<>();
            }
            List<Long> params = configDataParamAlgorithmRelationDOList.stream().map(ConfigDataParamAlgorithmRelationDO::getDataParamId).collect(Collectors.toList());
            findManageIdList.addAll(params);
        }
        // 筛选数据
        if (CollUtil.isEmpty(findManageIdList)){
            PageData<ConfigDataParamManagementDO> managementPage = dataParamManagement(paramManagementPageVO);
            return managementPage.transformData(ConfigDataParamManagementVO.class);
        }
        PageData<ConfigDataParamManagementDO> managementPage = pageManagement(paramManagementPageVO, findManageIdList);
        PageData<ConfigDataParamManagementVO> configDataParamManagementVOPageData = managementPage.transformData(ConfigDataParamManagementVO.class);
        Collection<ConfigDataParamManagementVO> data = configDataParamManagementVOPageData.getData();
        CollUtil.isEmpty(data);
        return configDataParamManagementVOPageData;
    }

    /**
     * 通过id进行删除数据
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ConfigDataParamManagementVO deleteById(Long id) {
        // 删除基本信息
        ConfigDataParamManagementDO paramManagementDO = dataParamManagementDAO.selectById(id);
        paramManagementDO.setStatus(9);
        dataParamManagementDAO.updateById(paramManagementDO);
        ConfigDataParamManagementVO paramManagementVO = BeanUtils.copyToObject(paramManagementDO, ConfigDataParamManagementVO.class);
        // 删除警告
        deleteAlarmByParamId(id);
        // 删除公式和参数
        deleteAlgorithmByParamId(id);

        return paramManagementVO;
    }

    /**
     * 按 ID 列表删除
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void deleteByIdList(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        ids.forEach(this::deleteById);
    }

    /**
     * 导出excel
     */
    @Override
    public void downloadManagement(HttpServletResponse response) {
        QueryWrapper<ConfigDataParamManagementDO> managementWrapper = new QueryWrapper<>();
        managementWrapper.eq("status", 0);
        List<ConfigDataParamManagementDO> configDataParamManagementDOS = dataParamManagementDAO.selectList(managementWrapper);
        List<ConfigDataParamManagementVO> configDataParamManagementVOS = BeanUtils.copyToList(configDataParamManagementDOS, ConfigDataParamManagementVO.class);
        List<DataParamExportExcel> dataParamExportExcels = BeanUtils.copyToList(configDataParamManagementVOS, DataParamExportExcel.class);
        // 使用 EasyExcel 导出数据到 Excel 文件
        EasyExcelUtils.exportExcel(response, "数据参量管理", dataParamExportExcels, DataParamExportExcel.class);
    }

    /**
     * 查询所有的数据参量
     */
    @Override
    public List<ConfigDataParamManagementVO> queryAllDataParam() {
        List<ConfigDataParamManagementDO> managementList = dataParamManagementDAO.selectList(Wrappers
                .<ConfigDataParamManagementDO>lambdaQuery()
                .eq(ConfigDataParamManagementDO::getStatus, 0));
        return BeanUtils.copyToList(managementList, ConfigDataParamManagementVO.class);
    }

    @Override
    public Map<Long, String> saveBatch(List<ConfigDataParamManagementVO> list) {
        List<ConfigDataParamManagementVO> collect = list.stream().map(this::save).collect(Collectors.toList());
        return collect.stream().collect(Collectors.toMap(ConfigDataParamManagementVO::getId, ConfigDataParamManagementVO::getCode));
    }

    /**
     * 地图代码和 ID 保存批次
     */
    @Override
    public Map<String, Long> mapCodeAndIdSaveBatch(List<ConfigDataParamManagementVO> list) {
        List<ConfigDataParamManagementVO> collect = list.stream().map(this::save).collect(Collectors.toList());
        return collect.stream().collect(Collectors.toMap(ConfigDataParamManagementVO::getCode, ConfigDataParamManagementVO::getId));
    }

    @Override
    public void updateBatch(List<ConfigDataParamManagementVO> list) {
    }

    /**
     * 查询参量数量
     */
    @Override
    public Long countAll() {
        return dataParamManagementDAO.selectCount(Wrappers.<ConfigDataParamManagementDO>lambdaQuery()
                .eq(ConfigDataParamManagementDO::getStatus, GenericStatusEnum.NORMAL.getValue()));
    }

    /**
     * 列表切割
     */
    @Override
    public List<ConfigDataParamManagementVO> listCut(Long offset, Long limit) {
        LambdaQueryWrapper<ConfigDataParamManagementDO> wrapper = Wrappers.<ConfigDataParamManagementDO>lambdaQuery()
                .eq(ConfigDataParamManagementDO::getStatus, GenericStatusEnum.NORMAL.getValue());
        wrapper.orderByAsc(ConfigDataParamManagementDO::getId);
        if (offset!= null && limit!= null) {
            wrapper.last("limit " + limit + " offset " + offset);
        }
        return listByWrappers(wrapper);
    }

    /**
     * 通过时间查询参量
     */
    @Override
    public List<ConfigDataParamManagementVO> listByCreateTime(Long time) {
        LambdaQueryWrapper<ConfigDataParamManagementDO> wrapper = Wrappers.<ConfigDataParamManagementDO>lambdaQuery()
                .gt(ConfigDataParamManagementDO::getCreateTime, time);
        return listByWrappers(wrapper);
    }

    @Override
    public List<ConfigDataParamManagementVO> listByUpdateTime(Long time) {
        LambdaQueryWrapper<ConfigDataParamManagementDO> wrapper = Wrappers.<ConfigDataParamManagementDO>lambdaQuery()
                .gt(ConfigDataParamManagementDO::getLastUpdateTime, time);
        wrapper.eq(ConfigDataParamManagementDO::getStatus, GenericStatusEnum.NORMAL.getValue());
        return listByWrappers(wrapper);
    }

    /**
     * 按 ID 列出
     */
    @Override
    public List<ConfigDataParamManagementVO> listByIds(List<Long> dataParamIds) {
        List<ConfigDataParamManagementDO> configDataParamManagementDOS = dataParamManagementDAO
                .selectList(Wrappers.<ConfigDataParamManagementDO>lambdaQuery()
                        .ne(ConfigDataParamManagementDO::getStatus, 9)
                        .in(ConfigDataParamManagementDO::getId, dataParamIds));
        if (CollUtil.isEmpty(configDataParamManagementDOS)) {
            return Collections.emptyList();
        }
        List<ConfigDataParamManagementVO> result = BeanUtils.copyToList(configDataParamManagementDOS, ConfigDataParamManagementVO.class);
        // 获取参量对应的算法
        Map<Long, ConfigAlgorithVO> mapAlgorithm = mapAlgorithm(dataParamIds);
        // 获取参量对应的参数
        Map<Long, List<ConfigParamVO>> mapParam = mapConfigParamList(result);
        // 获取参量对应的警告
        Map<Long, List<ConfigAlarmVO>> mapAlarmList = mapDataLabelList(dataParamIds);

        result.forEach(item -> {
            Long id = item.getId();
            Integer source = item.getSource();
            ConfigAlgorithVO algorithm = mapAlgorithm.getOrDefault(id, new ConfigAlgorithVO());
            if (DataParamSourceEnum.SYSTEM_CALCULATE.getCode().equals(source)) {
                item.setAlgorithmId(algorithm.getAlgorithId());
            }
            item.setConfigAlgorithVO(algorithm);
            item.setConfigParamVOList(mapParam.getOrDefault(id, new ArrayList<>()));
            item.setConfigAlarmVOList(mapAlarmList.getOrDefault(id, new ArrayList<>()));
        });
        return result;
    }

    /**
     * 按 ID 列出
     */
    @Override
    public Map<Long, ConfigDataParamManagementVO> mapByIds(List<Long> dataParamIds) {
        List<ConfigDataParamManagementVO> result = listByIds(dataParamIds);
        return result.stream().collect(Collectors.toMap(ConfigDataParamManagementVO::getId, item -> item));
    }

    @Override
    public List<ConfigDataParamManagementVO> listByParams(DataParamQueryVO dataParamQueryVO) {
        ConfigDataParamManagementPageVO management = BeanUtils.copyToObject(dataParamQueryVO, ConfigDataParamManagementPageVO.class);
        LambdaQueryWrapper<ConfigDataParamManagementDO> queryWrapper = buildQueryWrapper(management, new ArrayList<>());
        List<ConfigDataParamManagementDO> managements = dataParamManagementDAO.selectList(queryWrapper);
        return BeanUtils.copyToList(managements, ConfigDataParamManagementVO.class);
    }

    @Override
    public List<Long> queryParamsByParam(DevicePageQueryVO devicePageQueryVO) {
        List<Long> paramIds = dataParamManagementDAO.selectDeviceParams(devicePageQueryVO);
        return paramIds.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public List<DeviceParamVO> queryDataByParamIds(List<Long> paramIds) {
        if (CollUtil.isEmpty(paramIds)){
            return new ArrayList<>();
        }
        List<DevicePageQueryDO> deviceParamDOs = dataParamManagementDAO.queryDataByParamIds(paramIds);
        return BeanUtils.copyToList(deviceParamDOs, DeviceParamVO.class);
    }

    /**
     * 根据参数ID和名称查询数据
     */
    @Override
    public List<ConfigDataParamManagementVO> queryDataByParamIdsAndName(List<Long> DataParamIds, String factorName) {
        LambdaQueryWrapper<ConfigDataParamManagementDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ConfigDataParamManagementDO::getStatus, 0);
        if (StringUtils.isNotEmpty(factorName)) {
            wrapper.like(ConfigDataParamManagementDO::getName, factorName);
        }
        if (CollUtil.isNotEmpty(DataParamIds)) {
            wrapper.in(ConfigDataParamManagementDO::getId, DataParamIds);
        }
        return BeanUtils.copyToList(dataParamManagementDAO.selectList(wrapper), ConfigDataParamManagementVO.class);
    }

    @Override
    public void updateDataParamName(String equipmentName, List<Long> dataParamIdList) {
        ItemBO itemBO = new ItemBO();
        itemBO.setName(equipmentName);
        itemBO.setList(dataParamIdList);
        dataParamManagementDAO.updateDataParamName(itemBO);
    }

    /**
     * 通过code查参量名
     */
    @Override
    public ConfigDataParamManagementVO getParamNameByCode(String code) {
        ConfigDataParamManagementDO configDataParamManagementDO = dataParamManagementDAO.selectOne(Wrappers.lambdaQuery(ConfigDataParamManagementDO.class)
                .eq(ConfigDataParamManagementDO::getCode, code).ne(ConfigDataParamManagementDO::getStatus, GenericStatusEnum.DELETED.getValue()));
        return BeanUtils.copyToObject(configDataParamManagementDO,ConfigDataParamManagementVO.class);
    }

    private List<ConfigDataParamManagementVO> listByWrappers(LambdaQueryWrapper<ConfigDataParamManagementDO> wrapper) {
        List<ConfigDataParamManagementDO> configDataParamManagementList = dataParamManagementDAO
                .selectList(wrapper);

        if (CollUtil.isEmpty(configDataParamManagementList)) {
            return CollUtil.newArrayList();
        }

        List<Long> dataParamIds = configDataParamManagementList.stream()
                .map(ConfigDataParamManagementDO::getId)
                .distinct()
                .collect(Collectors.toList());

        return listByIds(dataParamIds);
    }

    /**
     * 通过参量id删除关联的公式以及参数。
     *
     * @param id
     */
    private void deleteAlgorithmByParamId(Long id) {

        QueryWrapper<ConfigDataParamAlgorithmRelationDO> algmRelationWrapper = new QueryWrapper<>();
        algmRelationWrapper.eq("data_param_id", id);
        List<ConfigDataParamAlgorithmRelationDO> algRelationList = algorithmRelationDAO.selectList(algmRelationWrapper);
        if (CollUtil.isEmpty(algRelationList)) {
            return;
        }
        List<Long> algIdList = algRelationList.stream().map(ConfigDataParamAlgorithmRelationDO::getAlgorithmId).collect(Collectors.toList());
        algorithmRelationDAO.delete(algmRelationWrapper);
        // 获取算法
        DataAlgorithmDO dataAlgorithmDO = dataAlgorithmDAO.selectById(algIdList.get(0));
        // 获取公式对应的参数
        List<Long> algParamIdList;
        if ("计算公式配置".equals(dataAlgorithmDO.getConfigurationScheme())) {
            // 获取公式数据
            QueryWrapper<DataAlgorithmFormulaConfigDO> formulaWrapper = new QueryWrapper<>();
            formulaWrapper.eq("algorithm_id", dataAlgorithmDO.getId());
            List<DataAlgorithmFormulaConfigDO> dataAlgorithmFormulaConfigDOS = dataAlgorithmFormulaConfigDAO.selectList(formulaWrapper);
            if (CollUtil.isEmpty(dataAlgorithmFormulaConfigDOS)) {
                return;
            }
            algParamIdList = dataAlgorithmFormulaConfigDOS.stream().map(DataAlgorithmFormulaConfigDO::getAlgorithmParamId).collect(Collectors.toList());
        } else {
            // 获取公式数据
            QueryWrapper<DataAlgorithmScriptConfigDO> scriptWrapper = new QueryWrapper<>();
            scriptWrapper.eq("algorithm_id", dataAlgorithmDO.getId());
            List<DataAlgorithmScriptConfigDO> algorithmScriptList = scriptConfigDAO.selectList(scriptWrapper);
            if (CollUtil.isEmpty(algorithmScriptList)) {
                return;
            }
            algParamIdList = algorithmScriptList.stream().map(DataAlgorithmScriptConfigDO::getParamConfigurationId).collect(Collectors.toList());
        }
        // 参数这些参数和参量关联信息
        QueryWrapper<ConfigDataParamAlgorithmParamRelationDO> paramRelationWrapper = new QueryWrapper<>();
        paramRelationWrapper.in("algorith_param_id", algParamIdList);
        paramRelationWrapper.eq("parent_param_id", id);
        paramRelationDAO.delete(paramRelationWrapper);
    }

    /**
     * 通过参数删除警告。
     */
    private void deleteAlarmByParamId(Long id) {
        // 删除警告部分
        QueryWrapper<ConfigDataParamAlarmRelationDO> alarmRelationDOQueryWrapper = new QueryWrapper<>();
        alarmRelationDOQueryWrapper.eq("data_param_id", id);
        List<ConfigDataParamAlarmRelationDO> alarmRelationDOList = configDataParamAlarmRelationDAO.selectList(alarmRelationDOQueryWrapper);
        if (CollUtil.isEmpty(alarmRelationDOList)) {
            return;
        }
        List<Long> alaramIdList = alarmRelationDOList.stream().map(ConfigDataParamAlarmRelationDO::getAlarmId).collect(Collectors.toList());
        // 删除警告
        dataAlarmDAO.deleteBatchIds(alaramIdList);
        configDataParamAlarmRelationDAO.delete(alarmRelationDOQueryWrapper);
    }

    /**
     * 获取分页数据。
     */
    private PageData<ConfigDataParamManagementDO> dataParamManagement(ConfigDataParamManagementPageVO paramManagementPageVO) {
        // 封装查询条件QueryWrapper对象

        LambdaQueryWrapper<ConfigDataParamManagementDO> queryWrapper = buildQueryWrapper(paramManagementPageVO, paramManagementPageVO.getIdList());
        // 分页查询数据报警点管理信息
        Page<ConfigDataParamManagementDO> page = Page.of(paramManagementPageVO.getPageNo(), paramManagementPageVO.getPageSize());
        return PageUtils.getPageData(dataParamManagementDAO.selectPage(page, queryWrapper), paramManagementPageVO);
    }

    /**
     * 获取分页数据。
     */
    private PageData<ConfigDataParamManagementDO> pageManagement(ConfigDataParamManagementPageVO paramManagementPageVO, List<Long> findManageIdList) {
        Page<ConfigDataParamManagementDO> page = Page.of(paramManagementPageVO.getPageNo(), paramManagementPageVO.getPageSize());
        Page<ConfigDataParamManagementDO> managementPage = dataParamManagementDAO.selectPage(page, buildQueryWrapper(paramManagementPageVO, findManageIdList));
        return PageUtils.getPageData(managementPage, paramManagementPageVO);
    }

    private LambdaQueryWrapper<ConfigDataParamManagementDO> buildQueryWrapper(ConfigDataParamManagementPageVO paramManagementPageVO,
                                                                              List<Long> findManageIdList) {
        LambdaQueryWrapper<ConfigDataParamManagementDO> managementDOQueryWrapper = new LambdaQueryWrapper<>();
        Optional.ofNullable(paramManagementPageVO.getIdList())
                .ifPresent(ids -> managementDOQueryWrapper.in(ConfigDataParamManagementDO::getId, ids));
        Optional.ofNullable(paramManagementPageVO.getIdNotList())
                .ifPresent(ids -> managementDOQueryWrapper.notIn(ConfigDataParamManagementDO::getId, ids));
        Optional.ofNullable(paramManagementPageVO.getCode())
                .ifPresent(code -> managementDOQueryWrapper.eq(ConfigDataParamManagementDO::getCode, code));
        Optional.ofNullable(paramManagementPageVO.getName())
                .ifPresent(name -> managementDOQueryWrapper.like(ConfigDataParamManagementDO::getName, name));
        Optional.ofNullable(paramManagementPageVO.getSource())
                .ifPresent(source -> managementDOQueryWrapper.eq(ConfigDataParamManagementDO::getSource, source));
        Optional.ofNullable(paramManagementPageVO.getAlias())
                .ifPresent(alias -> managementDOQueryWrapper.eq(ConfigDataParamManagementDO::getAlias, alias));
        Optional.ofNullable(paramManagementPageVO.getReportIdentifier())
                .ifPresent(reportIdentifier -> managementDOQueryWrapper
                        .eq(ConfigDataParamManagementDO::getReportIdentifier, reportIdentifier));
        Optional.ofNullable(paramManagementPageVO.getUnifiedIdentifier())
                .ifPresent(unifiedIdentifier -> managementDOQueryWrapper
                        .eq(ConfigDataParamManagementDO::getUnifiedIdentifier, unifiedIdentifier));
        Optional.ofNullable(paramManagementPageVO.getFrequencyUnit())
                .ifPresent(unit -> managementDOQueryWrapper
                        .eq(ConfigDataParamManagementDO::getFrequencyUnit, unit));
        Optional.ofNullable(paramManagementPageVO.getFrequency())
                .ifPresent(frequency -> managementDOQueryWrapper
                        .eq(ConfigDataParamManagementDO::getFrequency, frequency));
        Optional.ofNullable(paramManagementPageVO.getMeasurementUnit())
                .ifPresent(unit -> managementDOQueryWrapper
                        .eq(ConfigDataParamManagementDO::getMeasurementUnit, unit));
        Optional.ofNullable(paramManagementPageVO.getDataType())
                .ifPresent(type -> managementDOQueryWrapper
                        .eq(ConfigDataParamManagementDO::getDataType, type));
        Optional.ofNullable(paramManagementPageVO.getCreateTimeList())
                .ifPresent(time -> managementDOQueryWrapper
                        .between(ConfigDataParamManagementDO::getCreateTime, time.get(0), time.get(1)));
        Optional.ofNullable(paramManagementPageVO.getCreatorName())
                .ifPresent(name -> managementDOQueryWrapper
                        .eq(ConfigDataParamManagementDO::getCreatorName, name));
        if (CollUtil.isNotEmpty(paramManagementPageVO.getUnifiedIdentifiers())){
            managementDOQueryWrapper.in(ConfigDataParamManagementDO::getUnifiedIdentifier, paramManagementPageVO.getUnifiedIdentifiers());
        }
        if (CollUtil.isNotEmpty(findManageIdList)) {
            managementDOQueryWrapper.in(ConfigDataParamManagementDO::getId, findManageIdList);
        }
        List<Integer> statusList = paramManagementPageVO.getStatusList();
        if (CollUtil.isNotEmpty(statusList)) {
            managementDOQueryWrapper.in(ConfigDataParamManagementDO::getStatus, statusList);
        } else {
            managementDOQueryWrapper.eq(ConfigDataParamManagementDO::getStatus, 0);
        }
        managementDOQueryWrapper.orderByDesc(ConfigDataParamManagementDO::getId);  // 通过id倒序。
        return managementDOQueryWrapper;
    }

    //设备模型参量
    public  static  final String EXCEL_DATA_PARAM_VO = "ExcelDataParamVO";
    //参量频率
    public  static  final String EXCEL_FREQUENCY_VO = "ExcelFrequencyVO";
    //算法
    public  static  final String ALGORITHM_EXCEL_VO = "AlgorithmExcelVO";
    //算法参数
    public  static  final String EXCEL_ALGORITHM_PARAM_VO = "ExcelAlgorithmParamVO";
    //设备告警
    public  static  final String EXCEL_ALARM_VO = "ExcelAlarmVO";

    /**
     * 导入参量和算法关系
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importParamAndAlgorit(Map<String, List<?>> importData)  {
        //设备模型参量
        List<ConfigDataParamManagementDO> configDataParamManagementDOs =
                BeanUtils.copyToList(importData.get(EXCEL_DATA_PARAM_VO), ConfigDataParamManagementDO.class);

        //参量频率
        List<ExcelFrequencyVO> excelFrequencyVOS =
                BeanUtils.copyToList(importData.get(EXCEL_FREQUENCY_VO), ExcelFrequencyVO.class);
        //算法
        List<AlgorithmExcelVO> algorithmExcelVOs =
                BeanUtils.copyToList(importData.get(ALGORITHM_EXCEL_VO), AlgorithmExcelVO.class);
        //算法参数
        List<ExcelAlgorithmParamVO> excelAlgorithmParamVOs =
                BeanUtils.copyToList(importData.get(EXCEL_ALGORITHM_PARAM_VO), ExcelAlgorithmParamVO.class);
        //设备告警
        List<ExcelAlarmVO> excelAlarmVOs =
                BeanUtils.copyToList(importData.get(EXCEL_ALARM_VO), ExcelAlarmVO.class);

        if(CollectionUtils.isEmpty(configDataParamManagementDOs)){
            return;
        }

        //校验重复
        checkDup(configDataParamManagementDOs);

        //设置来源
        configDataParamManagementDOs.forEach(ConfigDataParamManagementDO::setSourceInteger);

        //参量基础表
        initParamManager(configDataParamManagementDOs, excelFrequencyVOS, algorithmExcelVOs);

        //name id  参量表
        QueryWrapper<ConfigDataParamManagementDO> configDataParamManagementDOQueryWrapper = new QueryWrapper<>();
        configDataParamManagementDOQueryWrapper.lambda().eq(ConfigDataParamManagementDO::getStatus,0);
        List<ConfigDataParamManagementDO> listParam = this.list(configDataParamManagementDOQueryWrapper);
        Map<String, Long> dataParamMapByName =
                listParam.stream().collect(Collectors.toMap(ConfigDataParamManagementDO::getName, BaseDO::getId));

        //算法保存
        Map<String, Long> algorithmMapByName = initAlgorit(algorithmExcelVOs, dataParamMapByName);

        //算法参量关系
        initParamRealtion(excelAlgorithmParamVOs, dataParamMapByName, algorithmMapByName);

        //警报
        initAlarm(excelAlarmVOs, listParam);
    }

    /**
     * 更新状态
     *
     * @param status          地位
     * @param dataParamIdList 数据参数 ID 列表
     */
    @Override
    public void updateStatus(Integer status, List<Long> dataParamIdList) {
        LambdaUpdateWrapper<ConfigDataParamManagementDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(ConfigDataParamManagementDO::getStatus, status).in(ConfigDataParamManagementDO::getId, dataParamIdList);
        dataParamManagementDAO.update(null, updateWrapper);
    }

    @Override
    public void downloadTeamplate(HttpServletResponse response) {
        EasyExcelUtils.exportExcel(response, "数据参量管理", null, DataExportBaseExcel.class);
    }

    /**
     * 校验重复
     */
    public void checkDup(List<ConfigDataParamManagementDO> configDataParamManagementDOs) {
        Map<String, List<ConfigDataParamManagementDO>> configDataGroup = configDataParamManagementDOs.stream().collect(Collectors.groupingBy(ConfigDataParamManagementDO::getName));
        StringBuilder error = new StringBuilder();
        configDataGroup.forEach((k,v)->{
            if(CollectionUtils.isNotEmpty(v) && v.size() > 1){
                error.append(k).append(";");
            }
        });

        //库中是否存在
        List<String> manNames = configDataParamManagementDOs.stream().map(ConfigDataParamManagementDO::getName).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(manNames)){
            return;
        }

        QueryWrapper<ConfigDataParamManagementDO> configWrapper = new QueryWrapper<>();
        configWrapper.lambda().eq(ConfigDataParamManagementDO::getStatus,0)
                .in(CollectionUtils.isNotEmpty(manNames),ConfigDataParamManagementDO::getName,manNames);
        List<ConfigDataParamManagementDO> list = this.list(configWrapper);
        if(CollectionUtils.isNotEmpty(list)){
            list.forEach(e-> error.append(e.getName()).append(";"));
        }
        if(StringUtils.isNotEmpty(error.toString())){
            throw new ServiceException("参量名称重复：" + error);
        }
    }

    /**
     * 保存参量基础表
     */
    public void initParamManager(List<ConfigDataParamManagementDO> configDataParamManagementDOs, List<ExcelFrequencyVO> excelFrequencyVOS, List<AlgorithmExcelVO> algorithmExcelVOs) {
        //设置编码
        configDataParamManagementDOs.forEach(e-> e.setCode(configRuleManagementServiceImpl.queryCodeBycode(codeRuleProperty.getDataParamCodeRule(),"")));
        this.saveBatch(configDataParamManagementDOs,500);

        //参量来源：设备采集 设置频率
        configDataParamManagementDOs.parallelStream()
                .filter(e->e.getSource() == ConfigDataParamManagementDO.DEVICE_ACQ)
                .forEach(e->{
                    List<ExcelFrequencyVO> excelFrequencyVO =
                            excelFrequencyVOS.stream().filter(son -> son.getDataParamName().equals(e.getName())).collect(Collectors.toList());
                    if(CollectionUtils.isNotEmpty(excelFrequencyVO)){
                        ExcelFrequencyVO frequency = excelFrequencyVO.get(0);
                        e.setFrequency(frequency.getFrequency());
                        e.setFrequencyUnit(frequency.getFrequencyUnit());
                    }
                });

        //参量来源：系统生成 设置频率 和算法名称
        configDataParamManagementDOs.parallelStream()
                .filter(e->e.getSource() == ConfigDataParamManagementDO.SYSTEM_CAL)
                .forEach(e->{
                    List<AlgorithmExcelVO> algorithms =
                            algorithmExcelVOs.stream().filter(son -> son.getDataParamName().equals(e.getName())).collect(Collectors.toList());
                    if(CollectionUtils.isNotEmpty(algorithms)){
                        AlgorithmExcelVO algorithmExcelVO = algorithms.get(0);
                        e.setFrequency(algorithmExcelVO.getFrequency());
                        e.setFrequencyUnit(algorithmExcelVO.getFrequencyUnit());
                        e.setAlgorithmName(algorithmExcelVO.getAlgorithmName());
                    }
                });
        //设置参量频率和算法名称
        saveOrUpdateBatch(configDataParamManagementDOs);
    }

    /**
     * 设置算法和参量的关系
     */
    @NotNull
    public Map<String, Long> initAlgorit(List<AlgorithmExcelVO> algorithmExcelVOs, Map<String, Long> dataParamMapByName) {
        if(CollectionUtils.isEmpty(algorithmExcelVOs)){
            return Collections.emptyMap();
        }

        Set<String> algoritNames = algorithmExcelVOs.stream().map(AlgorithmExcelVO::getAlgorithmName).collect(Collectors.toSet());
        QueryWrapper<DataAlgorithmDO> dataAlgorithmDOQueryWrapper = new QueryWrapper<>();
        dataAlgorithmDOQueryWrapper.lambda()
                .in(CollectionUtils.isNotEmpty(algoritNames),DataAlgorithmDO::getName,algoritNames)
                .eq(DataAlgorithmDO::getStatus,0);
        List<DataAlgorithmDO> algorithms = dataAlgorithmServiceImpl.list(dataAlgorithmDOQueryWrapper);
        if(CollectionUtils.isEmpty(algorithms)){
            return Collections.emptyMap();
        }
        //name id
        Map<String, Long> algorithmMapByName =
                algorithms.stream().collect(Collectors.toMap(DataAlgorithmDO::getName, BaseDO::getId));

        ArrayList<ConfigDataParamAlgorithmRelationDO> configDataParamAlgorithmRelationDOS = new ArrayList<>();
        algorithmExcelVOs.forEach(e->{
            ConfigDataParamAlgorithmRelationDO configDataParamAlgorithmRelationDO = new ConfigDataParamAlgorithmRelationDO();
            Long paramId = dataParamMapByName.get(e.getDataParamName());
            Long algoritId = algorithmMapByName.get(e.getAlgorithmName());
            if(Objects.nonNull(paramId) && Objects.nonNull(algoritId)){
                configDataParamAlgorithmRelationDO.setDataParamId(paramId);
                configDataParamAlgorithmRelationDO.setAlgorithmId(algoritId);
                configDataParamAlgorithmRelationDOS.add(configDataParamAlgorithmRelationDO);
            }
        });
        algorithmRelationDAO.insertBatch(configDataParamAlgorithmRelationDOS);
        return algorithmMapByName;
    }

    /**
     * 设置算法和参量的绑定
     */
    public void initParamRealtion(List<ExcelAlgorithmParamVO> excelAlgorithmParamVOs, Map<String, Long> dataParamMapByName, Map<String, Long> algorithmMapByName) {
        if(CollectionUtils.isEmpty(excelAlgorithmParamVOs) || CollectionUtils.isEmpty(algorithmMapByName)){
            return;
        }

        //算法的形参和实参绑定
        //所有算法参量涉及的算法id
        Set<Long> algorithmIdByParam =
                excelAlgorithmParamVOs.stream().map(e -> algorithmMapByName.get(e.getAlgorithmName())).collect(Collectors.toSet());
        QueryWrapper<DataAlgorithmFormulaConfigDO> dataAlgorithmFormulaConfigDOQueryWrapper = new QueryWrapper<>();
        dataAlgorithmFormulaConfigDOQueryWrapper.lambda()
                .in(CollectionUtils.isNotEmpty(algorithmIdByParam),DataAlgorithmFormulaConfigDO::getAlgorithmId,algorithmIdByParam);
        List<DataAlgorithmFormulaConfigDO> algorithmConfigS =
                dataAlgorithmFormulaConfigDAO.selectList(dataAlgorithmFormulaConfigDOQueryWrapper);
        if(CollectionUtils.isEmpty(algorithmConfigS)){
            return;
        }
        //算法对应的参量信息
        Set<Long> algorithmParamIds =
                algorithmConfigS.stream().map(DataAlgorithmFormulaConfigDO::getAlgorithmParamId).collect(Collectors.toSet());
        QueryWrapper<DataAlgorithmParamConfigDO> dataAlgorithmParamConfigWrapper = new QueryWrapper<>();
        dataAlgorithmParamConfigWrapper.lambda()
                .in(CollectionUtils.isNotEmpty(algorithmParamIds),DataAlgorithmParamConfigDO::getId,algorithmParamIds);
        List<DataAlgorithmParamConfigDO> dataAlgorithmParamConfigDOS =
                dataAlgorithmParamConfigDAO.selectList(dataAlgorithmParamConfigWrapper);
        if(CollectionUtils.isEmpty(dataAlgorithmParamConfigDOS)){
            return;
        }
        Map<Long, String> dataAlgorithmParamConfigById =
                dataAlgorithmParamConfigDOS.stream().collect(Collectors.toMap(DataAlgorithmParamConfigDO::getId, DataAlgorithmParamConfigDO::getDescription));
        //设置参量描述
        algorithmConfigS.forEach(e->e.setAlgorithmParamName(dataAlgorithmParamConfigById.get(e.getAlgorithmParamId())));

        //按算法和算法参量名称分组
        Map<String, Long> collect =
                algorithmConfigS.stream().collect(Collectors.toMap(e -> e.getAlgorithmId() + "/" + e.getAlgorithmParamName(), DataAlgorithmFormulaConfigDO::getAlgorithmParamId));

        List<ConfigDataParamAlgorithmParamRelationDO> configDataParamAlgorithmParamRelationDOS = new ArrayList<>();
        for (ExcelAlgorithmParamVO excelAlgorithmParamVO : excelAlgorithmParamVOs) {
            if("全局变量".equals(excelAlgorithmParamVO.getParamType())){
                continue;
            }
            Long parentParamId = dataParamMapByName.get(excelAlgorithmParamVO.getDataParamName());
            Long algoritId = algorithmMapByName.get(excelAlgorithmParamVO.getAlgorithmName());
            Long paramId = dataParamMapByName.get(excelAlgorithmParamVO.getBindDataParamName());
            Long algoritParamId = collect.get(algoritId + "/" + excelAlgorithmParamVO.getParamDesc());
            if(Objects.nonNull(parentParamId) && Objects.nonNull(algoritId) && Objects.nonNull(paramId) && Objects.nonNull(algoritParamId)){
                ConfigDataParamAlgorithmParamRelationDO configDataParamAlgorithmParamRelationDO = new ConfigDataParamAlgorithmParamRelationDO();
                configDataParamAlgorithmParamRelationDO.setParentParamId(parentParamId);
                configDataParamAlgorithmParamRelationDO.setDataParamId(paramId);
                configDataParamAlgorithmParamRelationDO.setAlgorithParamId(algoritParamId);
                configDataParamAlgorithmParamRelationDOS.add(configDataParamAlgorithmParamRelationDO);

            }
        }
        if(CollectionUtils.isNotEmpty(configDataParamAlgorithmParamRelationDOS)){
            paramRelationDAO.insertBatch(configDataParamAlgorithmParamRelationDOS);
        }
    }

    /**
     * 设置警告和算法
     */
    public void initAlarm(List<ExcelAlarmVO> excelAlarmVOs, List<ConfigDataParamManagementDO> listParam) {
        if(CollectionUtils.isEmpty(excelAlarmVOs)){
            return;
        }
        Map<String, ConfigDataParamManagementDO> managementByName =
                listParam.stream().collect(Collectors.toMap(ConfigDataParamManagementDO::getName, e -> e));
        List<DataAlarmDO> dataAlarmDOS = new ArrayList<>();
        for (ExcelAlarmVO excelAlarmVO : excelAlarmVOs) {
            ConfigDataParamManagementDO configDataParamManagementDO = managementByName.get(excelAlarmVO.getDataParamName());
            if(Objects.nonNull(configDataParamManagementDO)){
                DataAlarmDO dataAlarmDO = BeanUtils.copyToObject(excelAlarmVO, DataAlarmDO.class);
                dataAlarmDO.setCode(configDataParamManagementDO.getCode());
                dataAlarmDO.setDataParamId(configDataParamManagementDO.getId());
                dataAlarmDO.setName(configDataParamManagementDO.getName());
                dataAlarmDO.setParameterName(configDataParamManagementDO.getAlias());
                dataAlarmDO.setSource(configDataParamManagementDO.getSource());
                dataAlarmDOS.add(dataAlarmDO);
            }
        }
        dataAlarmDAO.insertBatch(dataAlarmDOS);
    }
}